package com.xbongbong.pro.statistic.service.result;

import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.pro.constant.CommonConstant;
import com.xbongbong.pro.constant.ElasticConstant;
import com.xbongbong.pro.domain.entity.ChartEntity;
import com.xbongbong.pro.service.toolbox.statistic.util.ChartResultUtil;
import com.xbongbong.pro.statistic.constant.SystemChartConstant;
import com.xbongbong.pro.statistic.enums.IndicatorRuleEnum;
import com.xbongbong.pro.statistic.enums.NumFormatEnum;
import com.xbongbong.pro.statistic.enums.PanoramaEnum;
import com.xbongbong.pro.statistic.enums.SystemCodeEnum;
import com.xbongbong.pro.statistic.enums.ValueTypeEnum;
import com.xbongbong.pro.statistic.result.pojo.AggsBucketsPojo;
import com.xbongbong.pro.statistic.result.pojo.ChartResultPkPojo;
import com.xbongbong.pro.statistic.result.pojo.ChartResultPojo;
import com.xbongbong.pro.statistic.result.pojo.ElasticAggsPojo;
import com.xbongbong.pro.statistic.result.pojo.MomYoyTimeListPojo;
import com.xbongbong.pro.statistic.result.pojo.PanoramaPojo;
import com.xbongbong.pro.statistic.result.pojo.dto.StatisticResultDTO;
import com.xbongbong.pro.statistic.result.pojo.dto.StatisticResultInfoDTO;
import com.xbongbong.pro.statistic.result.pojo.vo.ChartResultDetailVO;
import com.xbongbong.pro.statistic.result.pojo.vo.ChartResultPkDetailVO;
import com.xbongbong.pro.statistic.through.pojo.dto.ThroughDTO;
import com.xbongbong.saas.enums.business.QuotationEnum;
import com.xbongbong.sys.domain.entity.UserEntity;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 报价单相关统计
 *
 * @author 徐俊杰
 * @version v1.0
 * @date 2019/8/15 14:13
 * @since v1.0
 */
@Service
public class CrmQuotationResult extends ChartResultParentService implements ChartResultSystem, ChartResultPk, PanoramaResult {
    private static final Logger LOG = LoggerFactory.getLogger(CrmQuotationResult.class);

    @Override
    public Object getPkTarget(UserEntity userEntity, ChartResultPkPojo chartResultPkPojo, ChartResultPkDetailVO chartResultPkDetailVO) throws XbbException {
        SystemCodeEnum systemCodeEnum = chartResultPkPojo.getSystemCodeEnum();
        switch (systemCodeEnum) {
            case PK_QUOTATION_COUNT:
                return pkQuotationCount(userEntity, chartResultPkPojo, chartResultPkDetailVO);
            case PK_QUOTATION_AMOUNT:
                return pkQuotationAmount(userEntity, chartResultPkPojo, chartResultPkDetailVO);
            case PK_QUOTATION_CONVERSION:
                return pkQuotationConversion(userEntity, chartResultPkPojo, chartResultPkDetailVO);
            default:
                break;
        }
        return null;
    }

    /**
     * 系统pk范围规则指标公共接口
     *
     * @param userEntity            登录员工
     * @param chartEntity
     * @param chartResultPkPojo     pk参数
     * @param chartResultPkDetailVO 塞入pk结果
     * @return java.lang.Object
     * @throws XbbException
     * @author zcp
     * @date 2019/3/18 15:34
     * @version v1.0
     * @since v1.0
     */
    @Override
    public Object getPkRuleTarget(UserEntity userEntity, ChartEntity chartEntity, ChartResultPkPojo chartResultPkPojo, ChartResultPkDetailVO chartResultPkDetailVO) throws XbbException {
        SystemCodeEnum systemCodeEnum = chartResultPkPojo.getSystemCodeEnum();
        switch (systemCodeEnum) {
            case PK_QUOTATION_COUNT:
                return pkRuleQuotationCount(userEntity, chartEntity, chartResultPkPojo, chartResultPkDetailVO);
            case PK_QUOTATION_AMOUNT:
                return pkRuleQuotationAmount(userEntity, chartEntity, chartResultPkPojo, chartResultPkDetailVO);
            case PK_QUOTATION_CONVERSION:
                return pkRuleQuotationConversion(userEntity, chartEntity, chartResultPkPojo, chartResultPkDetailVO);
            default:
                break;
        }
        return null;
    }

    @Override
    public Object getTarget(ChartResultPojo chartResultPojo, ChartResultDetailVO chartResultDetailVO) throws XbbException {
        SystemCodeEnum systemCodeEnum = chartResultPojo.getSystemCodeEnum();
        switch (systemCodeEnum) {
            case QUOTATION_COUNT_CHART:
                return quotationCountChart(chartResultPojo, chartResultDetailVO);
            case QUOTATION_AMOUNT_CHART:
                return quotationAmountChart(chartResultPojo, chartResultDetailVO);
            case QUOTATION_CONVERSION_CHART:
                return quotationConversionChart(chartResultPojo, chartResultDetailVO);
            case QUOTATION_COUNT_HOME:
                return quotationCountHome(chartResultPojo, chartResultDetailVO);
            case QUOTATION_CUSTOMER_COUNT_HOME:
                return quotationCustomerCountHome(chartResultPojo, chartResultDetailVO);
            case QUOTATION_AMOUNT_HOME:
                return quotationAmountHome(chartResultPojo, chartResultDetailVO);
            case QUOTATION_CONVERSION_AMOUNT_HOME:
                return quotationConversionAmountHome(chartResultPojo, chartResultDetailVO);
            case QUOTATION_CONVERSION_HOME:
                return quotationConversionHome(chartResultPojo, chartResultDetailVO);
            default:
                break;
        }
        return null;
    }

    @Override
    public Object getValueTarget(ChartResultPojo chartResultPojo) throws XbbException {
        SystemCodeEnum systemCodeEnum = chartResultPojo.getSystemCodeEnum();
        switch (systemCodeEnum) {
            //报价单数量
            case QUOTATION_COUNT_BOARD:
                return quotationCountBoard(chartResultPojo);
            //报价单金额
            case QUOTATION_AMOUNT_BOARD:
                return quotationAmountBoard(chartResultPojo);
            //报价单转化率
            case QUOTATION_CONVERSION_BOARD:
                return quotationConversionBoard(chartResultPojo);
            default:
                break;
        }
        return null;
    }

    @Override
    public Object customer(PanoramaPojo panoramaPojo) throws XbbException {
        PanoramaEnum panoramaEnum = panoramaPojo.getPanoramaEnum();
        switch (panoramaEnum) {
            case CUSTOMER_QUOTATION_COUNT:
                return panoramaCustomerQuotationCount(panoramaPojo);
            case CUSTOMER_QUOTATION_AMOUNT:
                return panoramaCustomerQuotationAmount(panoramaPojo);
            default:
                break;
        }
        return null;
    }

    /**
     * 报价单数量PK
     *
     * @param userEntity 登录员工
     * @param chartResultPkPojo 入参
     * @param chartResultPkDetailVO 出参
     * @return com.xbongbong.pro.statistic.result.pojo.vo.ChartResultPkDetailVO
     * @throws XbbException getPkResult4Count会产生异常
     * @author 徐俊杰
     * @date 2019/8/22 17:31
     * @since v1.0
     */
    private ChartResultPkDetailVO pkRuleQuotationCount(UserEntity userEntity, ChartEntity chartEntity, ChartResultPkPojo chartResultPkPojo, ChartResultPkDetailVO chartResultPkDetailVO) throws XbbException {
        BoolQueryBuilder quotationQuery = chartRuleQueryHelp.quotationCountQuery(chartResultPkPojo, chartEntity);
        //报价人字段聚合
        String personField = QuotationEnum.getEsAttr4Keyword(QuotationEnum.QUOTATION_PERSON);
        TermsAggregationBuilder termsAggregationBuilder = AggregationBuilders.terms("aggs01").field(personField);
        termsAggregationBuilder.executionHint(ElasticConstant.EXECUTION_HINT);
        int pkType = chartResultPkPojo.getPkType();
        return pkRuleHelp.getPkResult4Count(userEntity, chartEntity, chartResultPkPojo, chartResultPkDetailVO, IndexTypeEnum.IDX_SAAS_QUOTATION, quotationQuery, termsAggregationBuilder, pkType);
    }

    /**
     * 报价单金额PK
     *
     * @param userEntity 登录员工
     * @param chartResultPkPojo 入参
     * @param chartResultPkDetailVO 出参
     * @return com.xbongbong.pro.statistic.result.pojo.vo.ChartResultPkDetailVO
     * @throws XbbException getPkResult4Double会产生异常
     * @author 徐俊杰
     * @date 2019/8/23 9:16
     * @since v1.0
     */
    private ChartResultPkDetailVO pkRuleQuotationAmount(UserEntity userEntity, ChartEntity chartEntity, ChartResultPkPojo chartResultPkPojo, ChartResultPkDetailVO chartResultPkDetailVO) throws XbbException {
        chartResultPkPojo.setValueTypeEnum(ValueTypeEnum.VALUE_MONEY);
        BoolQueryBuilder quotationQuery = chartRuleQueryHelp.quotationCountQuery(chartResultPkPojo, chartEntity);
        //报价人字段聚合
        String personField = QuotationEnum.getEsAttr4Keyword(QuotationEnum.QUOTATION_PERSON);
        //报价金额字段求和
        String sumField = QuotationEnum.getEsAttr4Keyword(QuotationEnum.AMOUNT);
        int pkType = chartResultPkPojo.getPkType();
        IndexTypeEnum indexTypeEnum = IndexTypeEnum.IDX_SAAS_QUOTATION;
        return pkRuleHelp.getPkResult4Double(userEntity, chartEntity, chartResultPkPojo, chartResultPkDetailVO, indexTypeEnum, quotationQuery, personField, sumField, pkType);
    }

    /**
     * 报价单转化率PK
     *
     * @param userEntity 登录员工
     * @param chartResultPkPojo 入参
     * @param chartResultPkDetailVO 出参
     * @return com.xbongbong.pro.statistic.result.pojo.vo.ChartResultPkDetailVO
     * @throws XbbException getPkResult4CountRate会产生异常
     * @author 徐俊杰
     * @date 2019/8/23 14:43
     * @since v1.0
     */
    private ChartResultPkDetailVO pkRuleQuotationConversion(UserEntity userEntity, ChartEntity chartEntity, ChartResultPkPojo chartResultPkPojo, ChartResultPkDetailVO chartResultPkDetailVO) throws XbbException {
        BoolQueryBuilder quotationQuery = chartRuleQueryHelp.quotationCountQuery(chartResultPkPojo, chartEntity);
        BoolQueryBuilder quotationCreateContractQuery = chartQueryHelp.quotationCreateContractCountQuery(chartResultPkPojo);
        //报价人字段聚合
        String personField = QuotationEnum.getEsAttr4Keyword(QuotationEnum.QUOTATION_PERSON);
        TermsAggregationBuilder termsAggregationBuilder = AggregationBuilders.terms("aggs01").field(personField);
        termsAggregationBuilder.executionHint(ElasticConstant.EXECUTION_HINT);
        int pkType = chartResultPkPojo.getPkType();
        return pkRuleHelp.getPkResult4CountRate(userEntity, chartEntity, chartResultPkPojo, chartResultPkDetailVO, IndexTypeEnum.IDX_SAAS_QUOTATION, quotationCreateContractQuery, quotationQuery, termsAggregationBuilder, pkType);
    }

    /**
     * 报价单数量PK
     *
     * @param userEntity 登录员工
     * @param chartResultPkPojo 入参
     * @param chartResultPkDetailVO 出参
     * @return com.xbongbong.pro.statistic.result.pojo.vo.ChartResultPkDetailVO
     * @throws XbbException getPkResult4Count会产生异常
     * @author 徐俊杰
     * @date 2019/8/22 17:31
     * @since v1.0
     */
    private ChartResultPkDetailVO pkQuotationCount(UserEntity userEntity, ChartResultPkPojo chartResultPkPojo, ChartResultPkDetailVO chartResultPkDetailVO) throws XbbException {
        BoolQueryBuilder quotationQuery = chartQueryHelp.quotationCountQuery(chartResultPkPojo);
        //报价人字段聚合
        String personField = QuotationEnum.getEsAttr4Keyword(QuotationEnum.QUOTATION_PERSON);
        TermsAggregationBuilder termsAggregationBuilder = AggregationBuilders.terms("aggs01").field(personField);
        termsAggregationBuilder.executionHint(ElasticConstant.EXECUTION_HINT);
        int pkType = chartResultPkPojo.getPkType();
        return pkHelp.getPkResult4Count(userEntity, chartResultPkPojo, chartResultPkDetailVO, IndexTypeEnum.IDX_SAAS_QUOTATION, quotationQuery, termsAggregationBuilder, pkType);
    }

    /**
     * 报价单金额PK
     *
     * @param userEntity 登录员工
     * @param chartResultPkPojo 入参
     * @param chartResultPkDetailVO 出参
     * @return com.xbongbong.pro.statistic.result.pojo.vo.ChartResultPkDetailVO
     * @throws XbbException getPkResult4Double会产生异常
     * @author 徐俊杰
     * @date 2019/8/23 9:16
     * @since v1.0
     */
    private ChartResultPkDetailVO pkQuotationAmount(UserEntity userEntity, ChartResultPkPojo chartResultPkPojo, ChartResultPkDetailVO chartResultPkDetailVO) throws XbbException {
        chartResultPkPojo.setValueTypeEnum(ValueTypeEnum.VALUE_MONEY);
        BoolQueryBuilder quotationQuery = chartQueryHelp.quotationCountQuery(chartResultPkPojo);
        //报价人字段聚合
        String personField = QuotationEnum.getEsAttr4Keyword(QuotationEnum.QUOTATION_PERSON);
        //报价金额字段求和
        String sumField = QuotationEnum.getEsAttr4Keyword(QuotationEnum.AMOUNT);
        int pkType = chartResultPkPojo.getPkType();
        IndexTypeEnum indexTypeEnum = IndexTypeEnum.IDX_SAAS_QUOTATION;
        return pkHelp.getPkResult4Double(userEntity, chartResultPkPojo, chartResultPkDetailVO, indexTypeEnum, quotationQuery, personField, sumField, pkType);
    }

    /**
     * 报价单转化率PK
     *
     * @param userEntity 登录员工
     * @param chartResultPkPojo 入参
     * @param chartResultPkDetailVO 出参
     * @return com.xbongbong.pro.statistic.result.pojo.vo.ChartResultPkDetailVO
     * @throws XbbException getPkResult4CountRate会产生异常
     * @author 徐俊杰
     * @date 2019/8/23 14:43
     * @since v1.0
     */
    private ChartResultPkDetailVO pkQuotationConversion(UserEntity userEntity, ChartResultPkPojo chartResultPkPojo, ChartResultPkDetailVO chartResultPkDetailVO) throws XbbException {
        BoolQueryBuilder quotationQuery = chartQueryHelp.quotationCountQuery(chartResultPkPojo);
        BoolQueryBuilder quotationCreateContractQuery = chartQueryHelp.quotationCreateContractCountQuery(chartResultPkPojo);
        //报价人字段聚合
        String personField = QuotationEnum.getEsAttr4Keyword(QuotationEnum.QUOTATION_PERSON);
        TermsAggregationBuilder termsAggregationBuilder = AggregationBuilders.terms("aggs01").field(personField);
        termsAggregationBuilder.executionHint(ElasticConstant.EXECUTION_HINT);
        int pkType = chartResultPkPojo.getPkType();
        return pkHelp.getPkResult4CountRate(userEntity, chartResultPkPojo, chartResultPkDetailVO, IndexTypeEnum.IDX_SAAS_QUOTATION, quotationCreateContractQuery, quotationQuery, termsAggregationBuilder, pkType);
    }

    /**
     * 图表中心报价单数量
     *
     * @param chartResultPojo 基础参数
     * @param chartResultDetailVO 回参
     * @return java.lang.Object
     * @throws XbbException getMomYoyResult,packageResult方法会产生异常
     * @author 徐俊杰
     * @date 2019/8/15 17:16
     * @since v1.0
     */
    private Object quotationCountChart(ChartResultPojo chartResultPojo, ChartResultDetailVO chartResultDetailVO) throws XbbException {
        StatisticResultDTO statisticResultDto = getMomYoyResult(chartResultPojo, I18nMessageUtil.getMessages(SystemChartConstant.QUOTATION_COUNT_LEGEND), I18nMessageUtil.getMessages(SystemChartConstant.QUOTATION_COUNT_UNIT), SystemChartConstant.COUNT);
        //右侧展示总数
        statisticResultDto.setTotalFlag(true);
        statisticResultDto.setValueTitle(I18nMessageUtil.getMessage(SystemChartConstant.QUOTATION_COUNT_VALUE_TITLE));
        return systemChartHelp.packageResult(statisticResultDto, chartResultPojo, chartResultDetailVO);
    }

    /**
     * 图表中心报价单金额
     *
     * @param chartResultPojo 入参
     * @param chartResultDetailVO 回参
     * @return java.lang.Object
     * @throws XbbException getMomYoyResult,packageResult会产生异常
     * @author 徐俊杰
     * @date 2019/8/16 9:41
     * @since v1.0
     */
    private Object quotationAmountChart(ChartResultPojo chartResultPojo, ChartResultDetailVO chartResultDetailVO) throws XbbException {
        StatisticResultDTO statisticResultDto = getMomYoyResult(chartResultPojo, I18nMessageUtil.getMessages(SystemChartConstant.QUOTATION_AMOUNT_LEGEND), I18nMessageUtil.getMessages(SystemChartConstant.QUOTATION_AMOUNT_UNIT), SystemChartConstant.SUM);
        //右侧展示总数
        statisticResultDto.setTotalFlag(true);
        statisticResultDto.setValueTitle(I18nMessageUtil.getMessage(SystemChartConstant.QUOTATION_AMOUNT_VALUE_TITLE));
        return systemChartHelp.packageResult(statisticResultDto, chartResultPojo, chartResultDetailVO);
    }

    /**
     * 图表中心报价单转化率
     *
     * @param chartResultPojo 入参
     * @param chartResultDetailVO 回参
     * @return java.lang.Object
     * @throws XbbException quotationCreateContractAgg,quotationCountAgg,packageResult会产生异常
     * @author 徐俊杰
     * @date 2019/8/16 14:34
     * @since v1.0
     */
    private Object quotationConversionChart(ChartResultPojo chartResultPojo, ChartResultDetailVO chartResultDetailVO) throws XbbException {
        //已生成订单的报价单
        ElasticAggsPojo createContractCountAggs = quotationCreateContractAgg(chartResultPojo, ValueTypeEnum.ARRAY_TYPE);
        List<AggsBucketsPojo> createContractCountList = createContractCountAggs.getBuckets();
        //报价单总量
        ElasticAggsPojo countAggs = quotationCountAgg(chartResultPojo, ValueTypeEnum.ARRAY_TYPE);
        List<AggsBucketsPojo> countList = countAggs.getBuckets();
        //报价单转化率
        ElasticAggsPojo conversionAggs = new ElasticAggsPojo();
        List<AggsBucketsPojo> conversionList = new ArrayList<>();
        if (createContractCountList.size() == countList.size()) {
            for (int i = 0; i < createContractCountList.size(); i++) {
                //已生成订单的报价单
                AggsBucketsPojo createContractCountItem = createContractCountList.get(i);
                Integer createContractCountValue = Integer.valueOf(createContractCountItem.getValue());
                //报价单总量
                AggsBucketsPojo countItem = countList.get(i);
                Integer countValue = Integer.valueOf(countItem.getValue());
                //报价单转化率
                Double conversionValue = ChartResultUtil.getRate(createContractCountValue, countValue);
                AggsBucketsPojo conversionItem = new AggsBucketsPojo("", conversionValue + "%");
                conversionList.add(conversionItem);
            }
            conversionAggs.setBuckets(conversionList);
        }
        //转订单数量
        //todo 穿透
        ThroughDTO conversionThrough = new ThroughDTO(chartResultPojo, SystemCodeEnum.QUOTATION_CONVERSION_CHART);
        ThroughDTO countThrough = new ThroughDTO(chartResultPojo, SystemCodeEnum.QUOTATION_COUNT_CHART);
        //是否画入表格内 0否1是
        Integer tableFlag = 1;
        StatisticResultInfoDTO createContractCountResult = new StatisticResultInfoDTO(conversionThrough, tableFlag, 0, 0,
                I18nMessageUtil.getMessage(SystemChartConstant.QUOTATION_CREATE_CONTRACT_COUNT_LEGEND), systemChartHelp.getUnit(I18nMessageUtil.getMessage(SystemChartConstant.QUOTATION_CREATE_CONTRACT_COUNT_UNIT)), createContractCountAggs);
        //报价数量
        StatisticResultInfoDTO countResult = new StatisticResultInfoDTO(countThrough, tableFlag, 0, 0,
                I18nMessageUtil.getMessage(SystemChartConstant.QUOTATION_SINGLE_COUNT_LEGEND), systemChartHelp.getUnit(I18nMessageUtil.getMessage(SystemChartConstant.QUOTATION_SINGLE_COUNT_UNIT)), countAggs);
        //报价单转化率
        StatisticResultInfoDTO conversionResult = new StatisticResultInfoDTO(null, tableFlag, 0, 0,
                I18nMessageUtil.getMessage(SystemChartConstant.QUOTATION_CONVERSION_LEGEND), systemChartHelp.getUnit(SystemChartConstant.QUOTATION_CONVERSION_UNIT), conversionAggs);
        List<StatisticResultInfoDTO> resultList = Arrays.asList(createContractCountResult, countResult, conversionResult);
        StatisticResultDTO statisticResultDto = new StatisticResultDTO(false, "", null, resultList);
        return systemChartHelp.packageResult(statisticResultDto, chartResultPojo, chartResultDetailVO);
    }

    /**
     * 简报看板报价单数量
     *
     * @param chartResultPojo 入参
     * @return java.lang.Object
     * @throws XbbException elasticAggs会产生异常
     * @author 徐俊杰
     * @date 2019/8/19 9:12
     * @since v1.0
     */
    private Object quotationCountBoard(ChartResultPojo chartResultPojo) throws XbbException {
        BoolQueryBuilder quotationQuery = chartQueryHelp.quotationCountQuery(chartResultPojo);
        ElasticAggsPojo quotationAggs = esHelper.elasticAggs(IndexTypeEnum.IDX_SAAS_QUOTATION, quotationQuery, null);
        return quotationAggs.getTotal();
    }

    /**
     * 简报看板报价单金额
     *
     * @param chartResultPojo 入参
     * @return java.lang.Object
     * @throws XbbException quotationAmountAgg会产生异常
     * @author 徐俊杰
     * @date 2019/8/19 9:26
     * @since v1.0
     */
    private Object quotationAmountBoard(ChartResultPojo chartResultPojo) throws XbbException {
        ElasticAggsPojo quotationAggs = quotationAmountAgg(chartResultPojo, ValueTypeEnum.VALUE_TYPE);
        return ChartResultUtil.formatValue2String(false, ValueTypeEnum.VALUE_MONEY, chartResultPojo.isThousandSwitch(), quotationAggs.getTotal(), NumFormatEnum.getByCode(chartResultPojo.getNumFormat()), chartResultPojo.getNumFormatFlag());
    }

    /**
     * 简报看板报价单转化率
     *
     * @param chartResultPojo 入参
     * @return java.lang.Object
     * @throws XbbException elasticAggs会产生异常
     * @author 徐俊杰
     * @date 2019/8/19 9:37
     * @since v1.0
     */
    private Object quotationConversionBoard(ChartResultPojo chartResultPojo) throws XbbException {
        //所有报价单
        BoolQueryBuilder countQuery = chartQueryHelp.quotationCountQuery(chartResultPojo);
        ElasticAggsPojo countAggs = esHelper.elasticAggs(IndexTypeEnum.IDX_SAAS_QUOTATION, countQuery, null);
        //生成合同的报价单
        BoolQueryBuilder quotationCreateContractQuery = chartQueryHelp.quotationCreateContractCountQuery(chartResultPojo);
        ElasticAggsPojo quotationCreateContractAggs = esHelper.elasticAggs(IndexTypeEnum.IDX_SAAS_QUOTATION, quotationCreateContractQuery, null);
        Integer countTotal = Integer.valueOf(countAggs.getTotal());
        Integer createContractCountTotal = Integer.valueOf(quotationCreateContractAggs.getTotal());
        return String.valueOf(ChartResultUtil.getRate(createContractCountTotal, countTotal));
    }

    /**
     * 首页报价单数量
     *
     * @param chartResultPojo 入参
     * @param chartResultDetailVO 出参
     * @return java.lang.Object
     * @throws XbbException quotationCountAgg,packageResult4One产生异常
     * @author 徐俊杰
     * @date 2019/8/19 10:09
     * @since v1.0
     */
    private Object quotationCountHome(ChartResultPojo chartResultPojo, ChartResultDetailVO chartResultDetailVO) throws XbbException {
        ElasticAggsPojo countAggs = quotationCountAgg(chartResultPojo, ValueTypeEnum.VALUE_TYPE);
        ThroughDTO throughDTO = new ThroughDTO(chartResultPojo, chartResultPojo.getSystemCodeEnum());
        return systemChartHelp.packageResult4One(countAggs, chartResultPojo, chartResultDetailVO, throughDTO,
                0, null, null, false, null);
    }

    /**
     * 首页报价客户数
     *
     * @param chartResultPojo 入参
     * @param chartResultDetailVO 出参
     * @return java.lang.Object
     * @throws XbbException quotationCustomer,packageResult4One会产生异常
     * @author 徐俊杰
     * @date 2019/8/19 11:15
     * @since v1.0
     */
    private Object quotationCustomerCountHome(ChartResultPojo chartResultPojo, ChartResultDetailVO chartResultDetailVO) throws XbbException {
        ElasticAggsPojo quotationCustomer = quotationCustomer(chartResultPojo, ValueTypeEnum.VALUE_TYPE);
        ThroughDTO throughDto = new ThroughDTO(chartResultPojo, chartResultPojo.getSystemCodeEnum());
        return systemChartHelp.packageResult4One(quotationCustomer, chartResultPojo, chartResultDetailVO, throughDto,
                1, IndicatorRuleEnum.QUOTATION_CUSTOMER_COUNT.getName(), systemChartHelp.getUnit(I18nMessageUtil.getMessage(CommonConstant.EACH)), false, IndicatorRuleEnum.QUOTATION_CUSTOMER_COUNT.getName());
    }

    /**
     * 首页报价单金额
     *
     * @param chartResultPojo 入参
     * @param chartResultDetailVO 出参
     * @return java.lang.Object
     * @throws XbbException quotationAmountAgg,packageResult4One会产生异常
     * @author 徐俊杰
     * @date 2019/8/19 10:24
     * @since v1.0
     */
    private Object quotationAmountHome(ChartResultPojo chartResultPojo, ChartResultDetailVO chartResultDetailVO) throws XbbException {
        ElasticAggsPojo amountAggs = quotationAmountAgg(chartResultPojo, ValueTypeEnum.ARRAY_TYPE);
        ThroughDTO throughDTO = new ThroughDTO(chartResultPojo, chartResultPojo.getSystemCodeEnum());
        return systemChartHelp.packageResult4One(amountAggs, chartResultPojo, chartResultDetailVO, throughDTO,
                1, IndicatorRuleEnum.QUOTATION_AMOUNT.getName(), NumFormatEnum.getByCode(chartResultPojo.getNumFormat()).getUnit(), true, IndicatorRuleEnum.QUOTATION_AMOUNT.getName());
    }

    /**
     * 首页报价单转化为合同的金额
     *
     * @param chartResultPojo 入参
     * @param chartResultDetailVO 出参
     * @return java.lang.Object
     * @throws XbbException createContractAmountAgg,packageResult4One会产生异常
     * @author 徐俊杰
     * @date 2019/8/19 14:32
     * @since v1.0
     */
    private Object quotationConversionAmountHome(ChartResultPojo chartResultPojo, ChartResultDetailVO chartResultDetailVO) throws XbbException {
        ElasticAggsPojo amountAggs = createContractAmountAgg(chartResultPojo, ValueTypeEnum.VALUE_TYPE);
        return systemChartHelp.packageResult4One(amountAggs, chartResultPojo, chartResultDetailVO, null,
                1, SystemCodeEnum.QUOTATION_CONVERSION_AMOUNT_HOME.getName(), NumFormatEnum.getByCode(chartResultPojo.getNumFormat()).getUnit(), true, IndicatorRuleEnum.QUOTATION_AMOUNT.getName());
    }

    /**
     * 首页报价单转化率
     *
     * @param chartResultPojo 入参
     * @param chartResultDetailVO 出参
     * @return java.lang.Object
     * @throws XbbException quotationCreateContractAgg,quotationCountAgg,packageResult4One会产生异常
     * @author 徐俊杰
     * @date 2019/8/19 14:13
     * @since v1.0
     */
    private Object quotationConversionHome(ChartResultPojo chartResultPojo, ChartResultDetailVO chartResultDetailVO) throws XbbException {
        //已生成合同的报价单
        ElasticAggsPojo createContractAggs = quotationCreateContractAgg(chartResultPojo, ValueTypeEnum.VALUE_TYPE);
        Integer createContract = StringUtil.toInt(createContractAggs.getTotal(), 0);
        //所有报价单
        ElasticAggsPojo countAggs = quotationCountAgg(chartResultPojo, ValueTypeEnum.VALUE_TYPE);
        Integer count = StringUtil.toInt(countAggs.getTotal(), 0);
        //转化率
        Double conversion = ChartResultUtil.getRate(createContract, count);
        ElasticAggsPojo conversionPojo = new ElasticAggsPojo();
        conversionPojo.setTotal(conversion.toString());
        // 跳过根据单位格式化数据，转化率不需要通过万元单位转化
        chartResultPojo.setValueTypeEnum(null);
        return systemChartHelp.packageResult4One(conversionPojo, chartResultPojo, chartResultDetailVO, null,
                0, null, null, false, null);
    }

    /**
     * 客户报价单数
     *
     * @param panoramaPojo 全景参数pojo
     * @return java.lang.String
     * @throws XbbException elasticAggs会出现异常
     * @author 徐俊杰
     * @date 2019/8/26 16:26
     * @since v1.0
     */
    private String panoramaCustomerQuotationCount(PanoramaPojo panoramaPojo) throws XbbException {
        BoolQueryBuilder quotationQuery = chartQueryHelp.panoramaQuery4Quotation(panoramaPojo);
        ElasticAggsPojo elasticAggsPojo = esHelper.elasticAggs(IndexTypeEnum.IDX_SAAS_QUOTATION, quotationQuery, null);
        return elasticAggsPojo.getTotal();
    }

    /**
     * 客户报价单金额
     *
     * @param panoramaPojo 全景参数pojo
     * @return java.lang.String
     * @throws XbbException getDouble4Total会出现异常
     * @author 徐俊杰
     * @date 2019/8/26 16:28
     * @since v1.0
     */
    private String panoramaCustomerQuotationAmount(PanoramaPojo panoramaPojo) throws XbbException {
        BoolQueryBuilder quotationQuery = chartQueryHelp.panoramaQuery4Quotation(panoramaPojo);
        String sumField = QuotationEnum.getEsAttr4Keyword(QuotationEnum.AMOUNT);
        double value = systemChartHelp.getDouble4Total(IndexTypeEnum.IDX_SAAS_QUOTATION, quotationQuery, sumField);
        return ChartResultUtil.formatValue2Double(false, ValueTypeEnum.VALUE_MONEY, false, value, NumFormatEnum.DEFAULT, false);
    }

    /**
     * 报价单数量或金额及其同比环比
     *
     * @param chartResultPojo 基本参数
     * @param legendList 说明列表
     * @param unitList 单位列表
     * @return com.xbongbong.pro.statistic.result.pojo.dto.StatisticResultDTO
     * @throws XbbException quotationCountAgg方法会发生异常
     * @author 徐俊杰
     * @date 2019/8/15 17:13
     * @since v1.0
     */
    private StatisticResultDTO getMomYoyResult(ChartResultPojo chartResultPojo, List<String> legendList, List<String> unitList, int type) throws XbbException {
        //------当前筛选时间的结果
        ElasticAggsPojo thisMonthAggsPojo = getMonthAggs(chartResultPojo, type);
        //先把chartResultPojo拷贝出一份，下面都用chartResultPojoCopy，防止时间的变更（环比、同比需要改变开始结束时间）对原有chartResultPojo内参数的影响
        ChartResultPojo chartResultPojoCopy = new ChartResultPojo();
        BeanUtil.copyProperties(chartResultPojo, chartResultPojoCopy);
        Integer startTime = chartResultPojo.getStartTime();
        Integer endTime = chartResultPojo.getEndTime();
        //获取环比同比各自的时间列表
        List<Integer> startTimeList = chartResultPojoCopy.getStartTimeList();
        MomYoyTimeListPojo momYoyTimeListPojo = ChartResultUtil.momYoyTimeListPojo(startTimeList);
        //环比时间处理
        ChartResultUtil.momOrYoyTime(chartResultPojoCopy, true, startTime, endTime);
        chartResultPojoCopy.setStartTimeList(momYoyTimeListPojo.getMomTimeListPojo().getStartTimeList());
        chartResultPojoCopy.setEndTimeList(momYoyTimeListPojo.getMomTimeListPojo().getEndTimeList());
        //------环比结果
        ElasticAggsPojo lastMonthAggsPojo = getMonthAggs(chartResultPojoCopy, type);
        //同比时间处理
        ChartResultUtil.momOrYoyTime(chartResultPojoCopy, false, startTime, endTime);
        chartResultPojoCopy.setStartTimeList(momYoyTimeListPojo.getYoyTimeListPojo().getStartTimeList());
        chartResultPojoCopy.setEndTimeList(momYoyTimeListPojo.getYoyTimeListPojo().getEndTimeList());
        //------同比结果
        ElasticAggsPojo lastYearAggsPojo = getMonthAggs(chartResultPojoCopy, type);
        //------处理环比、同比比例
        ElasticAggsPojo resultMom = systemChartHelp.getMomYoyResult(thisMonthAggsPojo, lastMonthAggsPojo);
        ElasticAggsPojo resultYoy = systemChartHelp.getMomYoyResult(thisMonthAggsPojo, lastYearAggsPojo);
        List<StatisticResultInfoDTO> statisticResultInfoDtoList = systemChartHelp.getInfoDtos4MomYoy(chartResultPojo, legendList, unitList, thisMonthAggsPojo, lastMonthAggsPojo, lastYearAggsPojo, resultMom, resultYoy);
        return new StatisticResultDTO(true, thisMonthAggsPojo.getTotal(), null, statisticResultInfoDtoList);
    }

    /**
     * 根据不同的统计类型获取结果
     *
     * @param resultPojo 入参
     * @param type 统计类型
     * @return com.xbongbong.pro.statistic.result.pojo.ElasticAggsPojo
     * @throws XbbException quotationCountAgg产生异常
     * @author 徐俊杰
     * @date 2019/8/16 9:35
     * @since v1.0
     */
    private ElasticAggsPojo getMonthAggs(ChartResultPojo resultPojo, int type) throws XbbException {
        ElasticAggsPojo monthAggsPojo = new ElasticAggsPojo();
        if (type == SystemChartConstant.COUNT) {
            monthAggsPojo = quotationCountAgg(resultPojo, ValueTypeEnum.ARRAY_TYPE);
        } else if (type == SystemChartConstant.SUM) {
            monthAggsPojo = quotationAmountAgg(resultPojo, ValueTypeEnum.ARRAY_TYPE);
        }
        return monthAggsPojo;
    }

    /**
     * 报价单数量
     *
     * @param chartResultPojo 图表查询基础参数
     * @param valueTypeEnum 数值类型枚举
     * @return com.xbongbong.pro.statistic.result.pojo.ElasticAggsPojo
     * @throws XbbException getCount4Agg产生异常
     * @author 徐俊杰
     * @date 2019/8/15 16:57
     * @since v1.0
     */
    private ElasticAggsPojo quotationCountAgg(ChartResultPojo chartResultPojo, ValueTypeEnum valueTypeEnum) throws XbbException {
        BoolQueryBuilder quotationQuery = chartQueryHelp.quotationCountQuery(chartResultPojo);
        String fieldTime = QuotationEnum.getEsAttr4Keyword(QuotationEnum.QUOTATION_TIME);
        return systemChartHelp.getCount4Agg(chartResultPojo, valueTypeEnum, IndexTypeEnum.IDX_SAAS_QUOTATION, quotationQuery, fieldTime);
    }

    /**
     * 报价单金额
     *
     * @param chartResultPojo 入参
     * @param valueTypeEnum 数值类型枚举
     * @return com.xbongbong.pro.statistic.result.pojo.ElasticAggsPojo
     * @throws XbbException getDouble4Agg产生异常
     * @author 徐俊杰
     * @date 2019/8/16 9:23
     * @since v1.0
     */
    private ElasticAggsPojo quotationAmountAgg(ChartResultPojo chartResultPojo, ValueTypeEnum valueTypeEnum) throws XbbException {
        chartResultPojo.setValueTypeEnum(ValueTypeEnum.VALUE_MONEY);
        BoolQueryBuilder quotationQuery = chartQueryHelp.quotationCountQuery(chartResultPojo);
        String sumField = QuotationEnum.getEsAttr4Keyword(QuotationEnum.AMOUNT);
        String timeField = QuotationEnum.getEsAttr4Keyword(QuotationEnum.QUOTATION_TIME);
        return systemChartHelp.getDouble4Agg(chartResultPojo, valueTypeEnum, IndexTypeEnum.IDX_SAAS_QUOTATION, quotationQuery, timeField, sumField);
    }

    /**
     * 转化为合同的报价单金额
     *
     * @param chartResultPojo 入参
     * @param valueTypeEnum 数值类型枚举
     * @return com.xbongbong.pro.statistic.result.pojo.ElasticAggsPojo
     * @throws XbbException getDouble4Agg产生异常
     * @author 徐俊杰
     * @date 2019/8/19 14:27
     * @since v1.0
     */
    private ElasticAggsPojo createContractAmountAgg(ChartResultPojo chartResultPojo, ValueTypeEnum valueTypeEnum) throws XbbException {
        BoolQueryBuilder quotationQuery = chartQueryHelp.quotationCreateContractCountQuery(chartResultPojo);
        String sumField = QuotationEnum.getEsAttr4Keyword(QuotationEnum.AMOUNT);
        String timeField = QuotationEnum.getEsAttr4Keyword(QuotationEnum.QUOTATION_TIME);
        return systemChartHelp.getDouble4Agg(chartResultPojo, valueTypeEnum, IndexTypeEnum.IDX_SAAS_QUOTATION, quotationQuery, timeField, sumField);
    }

    /**
     * 报价单数量（状态是已生成订单）
     *
     * @param chartResultPojo 入参
     * @param valueTypeEnum 数值类型枚举
     * @return com.xbongbong.pro.statistic.result.pojo.ElasticAggsPojo
     * @throws XbbException getCount4Agg产生异常
     * @author 徐俊杰
     * @date 2019/8/16 10:19
     * @since v1.0
     */
    private ElasticAggsPojo quotationCreateContractAgg(ChartResultPojo chartResultPojo, ValueTypeEnum valueTypeEnum) throws XbbException {
        BoolQueryBuilder quotationQuery = chartQueryHelp.quotationCreateContractCountQuery(chartResultPojo);
        String fieldTime = QuotationEnum.getEsAttr4Keyword(QuotationEnum.QUOTATION_TIME);
        return systemChartHelp.getCount4Agg(chartResultPojo, valueTypeEnum, IndexTypeEnum.IDX_SAAS_QUOTATION, quotationQuery, fieldTime);
    }

    /**
     * 报价单客户排重
     *
     * @param chartResultPojo 入参
     * @param valueTypeEnum 数值类型枚举
     * @return com.xbongbong.pro.statistic.result.pojo.ElasticAggsPojo
     * @throws XbbException distinctAggregations会产生异常
     * @author 徐俊杰
     * @date 2019/8/19 11:09
     * @since v1.0
     */
    private ElasticAggsPojo quotationCustomer(ChartResultPojo chartResultPojo, ValueTypeEnum valueTypeEnum) throws XbbException {
        BoolQueryBuilder quotationQuery = chartQueryHelp.quotationCountQuery(chartResultPojo);
        //时间字段
        String fieldTime = QuotationEnum.getEsAttr4Keyword(QuotationEnum.QUOTATION_TIME);
        //排重字段
        String fieldGroup = QuotationEnum.getEsAttr4Keyword(QuotationEnum.CUSTOMER_ID);
        return systemChartHelp.distinctAggregations(chartResultPojo, valueTypeEnum, IndexTypeEnum.IDX_SAAS_QUOTATION, quotationQuery, fieldTime, fieldGroup);
    }
}
